<template>
  <span :class="classes" :style="styles" ref="root">
    <img v-if="src" :src="src" @error="handleError" />
    <e-icon v-else-if="icon || customIcon" :type="icon" :custom="customIcon" ></e-icon>
    <span v-else ref="children" :class="[prefixCls + '-string']" :style="childrenStyle">
      <slot></slot>
    </span>
  </span>
</template>

<script setup>
import EIcon from "../icon"
import {getCurrentInstance,ref,unref,computed,watch,onBeforeMount,onMounted, useSlots,onUpdated} from "vue"
import {oneOf} from "../../utils/assist"

const prefixCls = ref('haloe-avatar');
const sizeList=['small', 'large', 'default'];

const props=defineProps({
  shape: {
    validator (value) {
      return oneOf(value, ['circle', 'square']);
    },
    default: 'circle'
  },
  size: {
    type: [String, Number],
    default () {
      const global = getCurrentInstance().appContext.config.globalProperties;
      return !global.$HALOE || global.$HALOE.size === '' ? 'default' : global.$HALOE.size;
    }
  },
  src: {
    type: String
  },
  icon: {
    type: String
  },
  customIcon: {
    type: String,
    default: ''
  }
})

const emits=defineEmits(['on-error'])

let scale=ref(1)
let childrenWidth=ref(0)
let isSlotShow=ref(false)
let slotTemp=ref()

let children=ref()
let root=ref()

const classes=computed(()=>{
  return [
    `${prefixCls.value}`,
    `${prefixCls.value}-${props.shape}`,
    {
      [`${prefixCls.value}-image`]: !!props.src,
      [`${prefixCls.value}-icon`]: !!props.icon || !!props.customIcon,
      [`${prefixCls.value}-${props.size}`]: oneOf(props.size, sizeList)
    }
  ]
})

const styles=computed(()=>{
  let style = {};
  if (props.size && !oneOf(props.size, sizeList)) {
    style.width = `${props.size}px`;
    style.height = `${props.size}px`;
    style.lineHeight = `${props.size}px`;
    style.fontSize = `${props.size/2}px`;
  }
  return style;
})

const childrenStyle=computed(()=>{
  let style={};
  if(unref(isSlotShow)){
    style={
      msTransform: `scale(${scale.value})`,
      WebkitTransform: `scale(${scale.value})`,
      transform: `scale(${scale.value})`,
      position: 'absolute',
      display: 'inline-block',
      left: `calc(50% - ${Math.round(childrenWidth.value / 2)}px)`
    };
  }
  return style
})

const setScale=()=>{
  isSlotShow.value=!props.src&&!props.icon;
  if(children.value){
    childrenWidth.value=children.value.offsetWidth
    const avatarWidth=unref(root).getBoundingClientRect().width
    if (avatarWidth - 8 < unref(childrenWidth)) {
      scale.value = (avatarWidth - 8) / unref(childrenWidth);
    } else {
      scale.value = 1;
    }
  }
}

const handleError=(e)=>{
  emits("on-error",e)
}

const slot=useSlots()

onBeforeMount(()=>{
  slotTemp.value=slot.default?slot.default():null
})

onMounted(() => {
  setScale()
})

onUpdated(() => {
  const _slot=slot.default ? slot.default() : null;
  if (_slot && _slot !== unref(slotTemp)) setScale();
})

watch(()=>props.size,(val,oldVal)=>{
  if(val!==oldVal) setScale()
})

</script>

<style>

</style>